package top.kaoshanji.ch12;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 代码清单 ch12-06：ConcurrentHashMap示例(12.5.3节、统计一个目录树的Java文件中的所有单词)
 * 并未执行
 * author kaoshanji
 * ^_^
 * create time 2024/11/29 21:03
 */
public class ConcurrentHashMapDemo {

    private static final Logger logger = LogManager.getLogger(ConcurrentHashMapDemo.class);

    // 也还是一个属性
    public static ConcurrentHashMap<String, Long> map = new ConcurrentHashMap<>();

    public static void main(String[] args) throws IOException, InterruptedException {

        logger.info("...代码清单 ch12-06：ConcurrentHashMap示例(12.5.3节、统计一个目录树的Java文件中的所有单词)...");

        int processors = Runtime.getRuntime().availableProcessors();
        ExecutorService executor = Executors.newFixedThreadPool(processors);
        Path pathToRoot = Path.of(".");
        for (Path p: descendants(pathToRoot)) {
            if (p.getFileName().toString().endsWith(".java")) {
                executor.execute(() -> process(p));
            }

            executor.shutdown();
            executor.awaitTermination(10, TimeUnit.MINUTES);

            map.forEach((k, v) -> {
                if (v >= 10) {
                    System.out.println(k + " occurs " + v + " times");
                }
            });

        }

    }

    public static void process(Path file) {
        try (var in = new Scanner(file)) {
            while (in.hasNext()) {
                String word = in.next();
                map.merge(word, 1L, Long::sum);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Set<Path> descendants(Path rootDir) throws IOException {

        try (Stream<Path> entries = Files.walk(rootDir)){
            return entries.collect(Collectors.toSet());
        }

    }


}
